<template>
  <div class="main-layout">
    <SidebarMenu
      :menus="menus"
      :collapsed="sidebarCollapsed"
      @toggle="toggleSidebar"
    />
    <div class="layout-content">
      <HeaderBar
        :collapsed="sidebarCollapsed"
        @toggle-sidebar="toggleSidebar"
      />
      <div class="content-wrapper">
        <PageTabs
          :tabs="tabs"
          :active="activeTab"
          @tab-change="handleTabChange"
          @tab-close="handleTabClose"
        />
        <div class="page-container">
          <router-view v-slot="{ Component }">
            <transition name="fade" mode="out-in">
              <component :is="Component" />
            </transition>
          </router-view>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import SidebarMenu from '@/components/layout/SidebarMenu.vue'
import HeaderBar from '@/components/layout/HeaderBar.vue'
import PageTabs, { type PageTab } from '@/components/layout/PageTabs.vue'
import { appChildRoutes, type AppRouteRecordRaw } from '@/router/routes'
import { useUserStore } from '@/stores/user'

const router = useRouter()
const route = useRoute()
const userStore = useUserStore()

const sidebarCollapsed = ref(false)
const tabs = ref<PageTab[]>([])
const activeTab = ref(route.path)

const filterRoutes = (routes: AppRouteRecordRaw[]): AppRouteRecordRaw[] =>
  routes
    .filter((item) => userStore.hasSomeRole((item.meta.roles as string[]) || []))
    .map((item) => ({
      ...item,
      children: item.children ? filterRoutes(item.children) : undefined
    }))

const menus = computed(() => filterRoutes(appChildRoutes))

const ensureTab = () => {
  const existing = tabs.value.find((tab) => tab.path === route.path)
  const currentTitle = (route.meta?.title as string) || '未命名'
  if (!existing) {
    tabs.value.push({
      path: route.path,
      title: currentTitle,
      closable: route.path !== '/dashboard'
    })
  } else {
    existing.title = currentTitle
  }
  activeTab.value = route.path
}

watch(
  () => route.path,
  () => {
    if (!route.meta?.public) {
      ensureTab()
    }
  },
  { immediate: true }
)

const handleTabChange = (path: string) => {
  if (path !== route.path) {
    router.push(path)
  }
}

const handleTabClose = (path: string) => {
  const index = tabs.value.findIndex((tab) => tab.path === path)
  if (index === -1) return
  tabs.value.splice(index, 1)
  if (path === route.path) {
    const fallback = tabs.value[index - 1] || tabs.value[index] || { path: '/dashboard' }
    router.push(fallback.path)
  }
}

const toggleSidebar = () => {
  sidebarCollapsed.value = !sidebarCollapsed.value
}
</script>

<style scoped lang="scss">
.main-layout {
  display: flex;
  min-height: 100vh;
  background: var(--bg-body);
}

.layout-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  transition: margin-left 0.3s ease;
}

.content-wrapper {
  flex: 1;
  padding: 0 var(--spacing-lg) var(--spacing-lg);
  background: var(--bg-body);
}

.page-container {
  margin-top: var(--spacing-md);
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.2s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
</style>
